import static org.junit.Assert.*;

import java.awt.Color;

import info.gridworld.actor.Actor;
import info.gridworld.actor.Flower;
import org.junit.Test;

import info.gridworld.actor.ActorWorld;
import info.gridworld.actor.Rock;
import info.gridworld.grid.Location;

public class JumperTest {
    private ActorWorld world;
    private Jumper jumper;
    private Jumper jumper_other;

    // test initialization
    @Test
    public void testJumperInt() {
        world = new ActorWorld();
        jumper = new Jumper();
        assertEquals(Color.RED, jumper.getColor());
        world = new ActorWorld();
        jumper = new Jumper(Color.GREEN);
        assertEquals(Color.GREEN, jumper.getColor());
    }


    @Test
    public void testAct() {
        // test move two cells when moving
        world = new ActorWorld();
        jumper = new Jumper();
        world.add(new Location(2, 2), jumper);
        world.step();
        assertEquals(new Location(0, 2), jumper.getLocation());

        // test jumper jump over rock
        world = new ActorWorld();
        jumper = new Jumper();
        world.add(new Location(2, 2), jumper);
        world.add(new Location(1, 2), new Rock());
        world.step();
        assertEquals(new Location(0, 2), jumper.getLocation());

        // test turn when the location two cells in front contains a rock
        world = new ActorWorld();
        jumper = new Jumper();
        world.add(new Location(2, 2), jumper);
        world.add(new Location(0, 2), new Rock());
        world.step();
        assertEquals(45, jumper.getDirection());

        // test turn when the location two cells in front contains a flower
        world = new ActorWorld();
        jumper = new Jumper();
        world.add(new Location(2, 2), jumper);
        world.add(new Location(0, 2), new Flower());
        world.step();
        assertEquals(new Location(0, 2), jumper.getLocation());

        // test jump when the location two cells in front of the jumper is out of the grid
        world = new ActorWorld();
        jumper = new Jumper();
        world.add(new Location(0, 2), jumper);
        world.step();
        assertEquals(45, jumper.getDirection());

        // test turn when the jumper is facing an edge of the grid
        world = new ActorWorld();
        jumper = new Jumper();
        world.add(new Location(0, 2), jumper);
        world.step();
        assertEquals(45, jumper.getDirection());

        // test turn when another actor (not a flower or a rock) is in the cell that is two cells in front of the jumper
        world = new ActorWorld();
        jumper = new Jumper();
        world.add(new Location(2, 2), jumper);
        world.add(new Location(0, 2), new Actor());
        world.step();
        assertEquals(45, jumper.getDirection());

        // test turn when jumper encounters another jumper in its path
        // case 1
        world = new ActorWorld();
        jumper = new Jumper();
        jumper_other = new Jumper();
        world.add(new Location(2, 2), jumper);
        world.add(new Location(4, 2), jumper_other);
        world.step();
        assertEquals(new Location(0, 2), jumper.getLocation());
        assertEquals(new Location(2, 2), jumper_other.getLocation());

        // case 2
        world = new ActorWorld();
        jumper = new Jumper();
        jumper_other = new Jumper();
        world.add(new Location(2, 2), jumper);
        world.add(new Location(0, 2), jumper_other);
        world.step();
        assertEquals(new Location(2, 2), jumper.getLocation());
        assertEquals(45, jumper_other.getDirection());

        //test no left flower when jumper leaves on a flower
        world = new ActorWorld();
        jumper = new Jumper();
        world.add(new Location(4, 2), jumper);
        world.add(new Location(2, 2), new Flower());
        world.step();
        assertEquals(new Location(2, 2), jumper.getLocation());
        world.step();
        assertEquals(null, jumper.getGrid().get(new Location(3, 5)));
    }
}
